
#include "e2d/ui/Layout.h"
#include "e2d/ui/State.h"

#include "sysx/System.h"
#include "e2d/ui/SceneTreeNodeEditor.h"
#include "e2d/ui/GraphEditor.h"
#include "e2d/ui/GameLayer.h"
#include "e2d/ui/HierarchyEditor.h"
#include "e2d/ui/CustumFileSystemLayer.h"
#include "e2d/ui/ActorEditor.h"
#include "e2d/ui/Utils.h"

#include "e2d/core/Inst.h"

#include "fxcc/imgui/FileSystemLayer.h"
#include "fxcc/imgui/FileSystemTreeNodeEditor.h"

using namespace e2d;

Layout::Layout()
{
	{

		m_SceneTreeNodeEditor = std::make_shared<e2d::SceneTreeNodeEditor>();
		this->m_Layers.push_back(m_SceneTreeNodeEditor);
	}

	{

		m_HierarchyEditor = std::make_shared<e2d::HierarchyEditor>();
		this->m_Layers.push_back(m_HierarchyEditor);
	}
	

	{
		m_GameLayer = std::make_shared<e2d::GameLayer>();
		this->m_Layers.push_back(m_GameLayer);
	}


	{
		m_GraphEditor = std::make_shared<e2d::GraphEditor>();
		this->m_Layers.push_back(m_GraphEditor);
	}

	{
		m_CustumFileSystemLayer = std::make_shared<e2d::CustumFileSystemLayer>();
		this->m_Layers.push_back(m_CustumFileSystemLayer);
	}
	{

		m_LoggerLayer = std::make_shared<e2d::LoggerLayer>();
		m_Layers.push_back(m_LoggerLayer);
	}

	{
		m_ActorEditor = std::make_shared<e2d::ActorEditor>();
		m_Layers.push_back(m_ActorEditor);
	}

	{
		m_MaterialEditor = std::make_shared<e2d::MaterialEditor>();
		m_Layers.push_back(m_MaterialEditor);
	}
	{
		m_EffectsEditor = std::make_shared<e2d::EffectsEditor>();
		m_Layers.push_back(m_EffectsEditor);
	}

}



void Layout::Inst()
{
	ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport());

	OnMainMenuBar();

	for (auto it : m_Layers)
	{
		it->Inst();
	}
}

void Layout::Handle()
{
	auto& sg = e2d::State::Inst();

	for (auto it : m_Layers)
	{
		it->Handle();
	}
	if (sg.saveInst)
	{
		OnSaveData();
		sg.saveInst = false;
	}
	if (sg.loadInst)
	{
		OnLoadData(sg.loadPath);
		sg.loadInst = false;

	}

	if (sg.newInst)
	{
		NewInstance();
		
		sg.hireEntityFlag = true;
		sg.selectedEntity = 0;

		sg.newInst = false;
	}


	// set editing scene

	//m_HierarchyEditor->m_Inst = scene.get();

}

void Layout::View()
{
	for (auto it : m_Layers)
	{
		it->MenuItem();
	}
}

void e2d::Layout::SetScene(std::shared_ptr<e2d::Scene> scene)
{
	m_GraphEditor->m_Scene = scene;
	m_GameLayer->m_Scene = scene;
	m_SceneTreeNodeEditor->m_Inst = scene;
	m_HierarchyEditor->m_Scene = scene;

}

void e2d::Layout::NewInstance()
{
	e2d::Utils::NewInstance();
}

void Layout::OnMainMenuBar()
{
	using Instance = e2d::Inst;

	auto& sg = State::Inst();

	ImGuiIO& io = ImGui::GetIO();

	if (ImGui::BeginMainMenuBar())
	{
		if (ImGui::BeginMenu("Files"))
		{
			if (ImGui::MenuItem("New", "Ctrl+N"))
			{
				sg.newInst = true;

			}
			if (ImGui::MenuItem("Open", "Ctrl+L"))
			{
				OnLoad();
			}
			if (ImGui::BeginMenu("Recent"))
			{
				for (const auto& it :e2d::Utils::m_Cache.m_Recents)
				{
					if (!it.m_Path.empty())
					{
						if (ImGui::MenuItem(it.m_Path.c_str()))
						{
							sg.loadInst = true;
							sg.loadPath = it.m_Path;
						}
					}
				}
				ImGui::EndMenu();
			}
			if (ImGui::MenuItem("Save", "Ctrl+S"))
			{
				OnSave();

			}
			if (ImGui::MenuItem("Save As", "Ctrl+Shift+S"))
			{
				OnSaveAs();
			}

			ImGui::EndMenu();
		}
		if (ImGui::BeginMenu("View"))
		{
			View();

			ImGui::EndMenu();
		}
		if (ImGui::BeginMenu("Action"))
		{

			ImGui::EndMenu();

		}
		if (ImGui::BeginMenu("About"))
		{
			ImGui::EndMenu();
		}

		ImGui::EndMainMenuBar();
	}


	if ((io.KeyCtrl && ImGui::IsKeyReleased(ImGuiKey_S)))
	{
		OnSave();
	}

	if ((io.KeyCtrl && ImGui::IsKeyReleased(ImGuiKey_L)))
	{
		OnLoad();
	}
	if ((io.KeyCtrl && io.KeyShift && ImGui::IsKeyReleased(ImGuiKey_S)))
	{
		OnSaveAs();
	}
};


void Layout::OnDestroy()
{
	OnSaveData();
	
	for (auto layer : m_Layers)
	{
		layer->OnDestroy();
	}
}

void Layout::OnSave()
{
	auto& sg = State::Inst();

	if (e2d::Utils::m_Inst.m_FileHeader.Empty())
	{
		std::string path = sysx::System::SaveDialog("Save Path", filters, e2d::Utils::m_Inst.m_FileHeader.FileName());
		e2d::Utils::m_Inst.m_FileHeader.SetFullPath(path);
	}
	OnSaveData();

}

void Layout::OnSaveAs()
{
	std::string path = sysx::System::SaveDialog("Save Path", filters, e2d::Utils::m_Inst.m_FileHeader.FileName());
	e2d::Utils::m_Inst.m_FileHeader.SetFullPath(path);

	OnSaveData();
}

void e2d::Layout::OnSaveData()
{
	e2d::Utils::OnSaveData();
}

void Layout::OnLoad()
{
	auto& sg = State::Inst();
	std::string path = sysx::System::OpenDialog("Open Path", filters);

	if (!path.empty())
		OnLoadData(path);
	else
	{
		ztclog::info("Load Path is empty");
	}
}

void e2d::Layout::OnLoadData(const std::string& path)
{
	e2d::Utils::OnLoadData(path);
	
	{
		e2d::Utils::SetSceneFromInst();
		SetScene(e2d::Utils::m_Inst.m_Scene);
	}

}


